/* server.c                                               *
  * CS4235 - Programming Assignment #1  *
  * Dustin Shiflett & Johannes Schuett        */

#include <unistd.h> /* For usleep() */
#include <stdio.h> /* For printf's */
#include <stdlib.h> /*itoa*/
#include <string.h> /* For Strings */
#include <sys/types.h> /* For Filesize */
#include <sys/stat.h> /* For Filesize */

#include "server.h"

int debug = 0;

int main(int argc, char *argv[]) {
    FILE *serverPW, *checkPW;
    struct stat serverPWStat, checkPWStat;
    int same, i, n, delay;
    char ch1, ch2;
    char *msg;
    unsigned long diffByte, serverPWSize, checkPWSize, p;
    unsigned int sleepDelay = 1000;
    int bits[8] = {0,0,0,0,0,0,0,0};
    
    /*Disable output buffering*/
    setvbuf (stdout, 0, _IONBF, 0);
    
    /*checking number of command line arguments*/
    if((argc != 4) && (argc != 5)) {
        printf("usage: %s <Password File to Check> <Secret Message> <Delay(ms)> [-d]\n-d: Optional Debug/Verbose Output\n", argv[0]);
        exit(1);
    }
    /*./server check.pw message 100*/
    /*should debug output be enabled?*/
    if(argc == 5) {
        if (strcmp("-d", argv[4]) == 0) {
            debug = 1;
            dprint("Debug/verbose option enabled.\n");
        }
    }
    
    /*Get size & existence info*/
    stat("server.pw", &serverPWStat);
    serverPWSize = serverPWStat.st_size;
    daprint("server.pw size: %lu.\n", serverPWSize);
    
    if(serverPWSize == 0) {
        printError("server.pw is 0 length.\n");
        exit(1);
    }
    
    stat(argv[1], &checkPWStat);
    checkPWSize = checkPWStat.st_size;
    daprint("Password to check size: %lu.\n", checkPWSize);
    
    if(checkPWSize == 0) {
        printError("Password file to check is 0 length.\n");
        exit(1);
    }
    
    /*Open the files*/
    if((serverPW = fopen("server.pw", "rb"))==NULL) {
        printError("Cannot open server.pw.\n");
        exit(1);
    }
    if((checkPW = fopen(argv[1], "rb"))==NULL) {
        printError("Cannot open password file to check.\n");
        exit(1);
    }
    dprint("File handles successfully opened.\n");
    
    /*Start comparison*/
    diffByte = 0;
    same = 1;
    while(!feof(checkPW)) {
    /*for(p=0; p < checkPWSize; p++) {
        if (p > serverPWSize) {
            dprint("Checking exceeded boundary of server.pw--bad password!\n")
            same = 0;
            break;
        }*/
        ch1 = fgetc(serverPW);
        if(ferror(serverPW)) {
            printError("Error reading server.pw.\n");
            exit(1);
        }
        ch2 = fgetc(checkPW);
        if(ferror(checkPW)) {
            printError("Error reading password file to check.\n");
            exit(1);
        }
        if(ch1 != ch2) {
            if(debug) {
                printf("Files do not match. Bad Password! %c != %c at byte number: %lu\n", ch1, ch2, diffByte);
            }
            same = 0;
            break;
        }
        diffByte++;
        /* usleep(100); */ /*Increase comparison time based on how many iterations*/
        if(debug) {
            if (p%200 == 0)
                printf("-");
        }
    }
    
    /*Close file handles*/
    if(fclose(serverPW) == EOF) {
        printError("Error closing server.pw.\n");
        exit(1);
    }
    if(fclose(checkPW) == EOF) {
        printError("Error closing password file to check.\n");
        exit(1);
    }
    
    if(!same) {
        dprint("Password does not match.\n");
        exit(1);
    }
    
    dprint("Password files match!\n");
    
    delay = atoi(argv[3]);
    i = strlen(argv[2]);
    msg = (char*)calloc(i + 1, sizeof(char));
    if(msg == NULL) {
        printError("FATAL ERROR: Memory allocation for message processing failed!\n");
        exit(1);
    }
    strncpy(msg, argv[2], i);
    
    daprint("Message: %s\n", msg);
    
    printf("Logging in");
    dprint("\n");
    
    /*Process message*/
    for (i=0; i < strlen(msg); i++) {
        /*itoa(msg[i], &binMsg, 2);*/ /*Doesn't work on Helsinki in C*/
        ch1 = msg[i];
        for(n=0; n < 8; n++) {
            if((1<<n) &ch1) {
                bits[n] = 1;
            } else {
                bits[n] = 0;
            }
        }
        if(debug) {
            printf("Char: %c\t\t", ch1);
            printf("Binary: ");
            for(n=7; n >= 0; n--) {
                printf("%i", bits[n]);
            }
            dprint("\t\t");
        }
        for(n=7; n >= 0; n--) {
            if(bits[n] == 1) {
                usleep(1000*delay);
            }
            printf(".");
        }
        dprint("\n");
    }

    /*Cleanup*/
    free(msg);
    
    return 0;
}
